/**
 * 新浪数据源实现
 * 实现从新浪财经获取股票数据
 */

import StockDataSource from './stockDataSource.js';
import request from '../utils/request.js';

class SinaDataSource extends StockDataSource {
	/**
	 * 搜索股票
	 * @param {String} keyword - 搜索关键词
	 * @returns {Promise<Object>} 返回格式化的股票列表
	 */
	async searchStock(keyword) {
		try {
			const timestamp = Date.now();
			const url = `https://suggest3.sinajs.cn/suggest/type=&key=${keyword}&name=suggestdata_${timestamp}`;
			
			const response = await request.get({
				url,
				useCache: false // 搜索不使用缓存
			});
			
			// 解析返回数据
			return this._parseSearchResult(response, timestamp);
		} catch (error) {
			console.error('搜索股票失败:', error);
			throw error;
		}
	}

	/**
	 * 获取分时K线数据
	 * @param {Object} params - 请求参数
	 * @returns {Promise<Object>} 返回格式化的K线数据
	 */
	async getMinuteKLine(params) {
		try {
			const { stockCode, period, count = 170 } = params;
			const varName = `${period}_today`;
			const url = `https://ifzq.gtimg.cn/appstock/app/kline/mkline?param=${stockCode},${period},,${count}&_var=${varName}`;
			
			const response = await request.get({
				url,
				data: params,
				useCache: true
			});
			
			// 解析返回数据
			return this._parseKLineResult(response, varName);
		} catch (error) {
			console.error('获取分时K线失败:', error);
			throw error;
		}
	}

	/**
	 * 获取其他K线数据
	 * @param {Object} params - 请求参数
	 * @returns {Promise<Object>} 返回格式化的K线数据
	 */
	async getOtherKLine(params) {
		try {
			const {
				stockCode,
				period,
				startDate = '2010-01-01',
				endDate = this._getTodayDate(),
				count = 160,
				adjust = 'qfq'
			} = params;
			
			const url = `https://web.ifzq.gtimg.cn/appstock/app/fqkline/get?_var=kline_day&param=${stockCode},${period},${startDate},${endDate},${count},${adjust}`;
			
			const response = await request.get({
				url,
				data: params,
				useCache: true
			});
			
			// 解析返回数据
			return this._parseKLineResult(response, 'kline_day');
		} catch (error) {
			console.error('获取其他K线失败:', error);
			throw error;
		}
	}

	/**
	 * 解析搜索结果
	 * @param {String} response - 原始响应数据
	 * @param {Number} timestamp - 时间戳
	 * @returns {Object} 格式化的搜索结果
	 */
	_parseSearchResult(response, timestamp) {
		try {
			// 提取数据部分：var suggestdata_xxx="数据";
			const regex = new RegExp(`var suggestdata_${timestamp}="(.*)";?`);
			const match = response.match(regex);
			
			if (!match || !match[1]) {
				return {
					code: 0,
					msg: '成功',
					stockList: []
				};
			}
			
			const dataStr = match[1];
			const items = dataStr.split(';').filter(item => item.trim());
			
			const stockList = [];
			items.forEach(item => {
				const parts = item.split(',');
				if (parts.length >= 5 && parts[1] === '11') { // 只处理A股
					stockList.push({
						stockCode: parts[3],
						stockNumber: parts[2],
						stockName: parts[4]
					});
				}
			});
			
			return {
				code: 0,
				msg: '成功',
				stockList
			};
		} catch (error) {
			console.error('解析搜索结果失败:', error);
			return {
				code: -1,
				msg: '解析失败',
				stockList: []
			};
		}
	}

	/**
	 * 解析K线结果
	 * @param {String} response - 原始响应数据
	 * @param {String} varName - 变量名
	 * @returns {Object} 格式化的K线数据
	 */
	_parseKLineResult(response, varName) {
		try {
			// 提取JSON数据：varName={...}
			const regex = new RegExp(`${varName}=(.*)$`);
			const match = response.match(regex);
			
			if (!match || !match[1]) {
				throw new Error('数据格式错误');
			}
			
			const jsonData = JSON.parse(match[1]);
			
			if (jsonData.code !== 0) {
				throw new Error(jsonData.msg || '获取数据失败');
			}
			
			// 获取股票代码
			const stockCode = Object.keys(jsonData.data)[0];
			const stockInfo = jsonData.data[stockCode];
			const qtInfo = stockInfo.qt[stockCode];
			
			// 获取周期数据
			let period = '';
			let partList = [];
			
			// 查找周期key（m5/m15/m30/m60/day/week/month）
			for (let key in stockInfo) {
				if (key !== 'qt' && key !== 'prec' && key !== 'mx_price' && key !== 'version') {
					period = key;
					partList = stockInfo[key];
					break;
				}
			}
			
			// 格式化partList
			const formattedPartList = partList.map(item => {
				return [
					item[0], // 时间
					parseFloat(item[1]), // 开盘价
					parseFloat(item[2]), // 收盘价
					parseFloat(item[3]), // 最高价
					parseFloat(item[4]), // 最低价
					parseFloat(item[5]) // 成交量
				];
			});
			
			// 提取市盈率和总市值（根据腾讯API返回的数组索引）
			const peRatio = qtInfo[39] ? parseFloat(qtInfo[39]) : null;
			const totalMarketValue = qtInfo[45] ? parseFloat(qtInfo[45]) * 10000 : null; // 转换为元
			
			return {
				code: 0,
				msg: '成功',
				stockData: {
					stockCode: stockCode,
					stockName: qtInfo[1],
					stockNumber: qtInfo[2],
					lastPrice: parseFloat(qtInfo[3]),
					yesterPrice: parseFloat(qtInfo[4]),
					todayPrice: parseFloat(qtInfo[5]),
					volume: parseFloat(qtInfo[6]),
					updateTime: qtInfo[30],
					priceChange: parseFloat(qtInfo[31]),
					priceChangePercent: parseFloat(qtInfo[32]),
					highPrice: parseFloat(qtInfo[33]),
					lowPrice: parseFloat(qtInfo[34]),
					closePrice: parseFloat(qtInfo[3]),
					turnover: parseFloat(qtInfo[37]),
					volatility: parseFloat(qtInfo[43]),
					peRatio: peRatio, // 市盈率
					totalMarketValue: totalMarketValue // 总市值（元）
				},
				part: period,
				partList: formattedPartList
			};
		} catch (error) {
			console.error('解析K线结果失败:', error);
			throw {
				code: -1,
				msg: error.message || '解析失败'
			};
		}
	}

	/**
	 * 获取今天日期
	 * @returns {String} 格式：YYYY-MM-DD
	 */
	_getTodayDate() {
		const today = new Date();
		const year = today.getFullYear();
		const month = String(today.getMonth() + 1).padStart(2, '0');
		const day = String(today.getDate()).padStart(2, '0');
		return `${year}-${month}-${day}`;
	}
}

export default SinaDataSource;

